<template>
  <el-dialog
    :title="title"
    :visible.sync="visibleProxy"
    width="80%"
    :close-on-click-modal="false"
    @open="onOpen"
  >
    <div class="map-toolbar">
      <el-input
        v-model="keyword"
        placeholder="请输入地址或地点名称进行搜索"
        clearable
        class="search-input"
        @keyup.enter.native="onSearch"
      >
        <el-button slot="append" icon="el-icon-search" @click="onSearch">搜索</el-button>
      </el-input>
      <div class="coord-display">
        <span>经度：{{ longitude }}</span>
        <span>纬度：{{ latitude }}</span>
      </div>
    </div>

    <div class="map-container" ref="mapContainer"></div>

    <span slot="footer" class="dialog-footer">
      <el-button @click="close">取 消</el-button>
      <el-button type="primary" @click="confirm">确 定</el-button>
    </span>
  </el-dialog>
</template>

<script>
import loadTencentMap from '@/utils/loadTencentMap'

export default {
  name: 'TencentMapPicker',
  model: {
    prop: 'visible',
    event: 'input'
  },
  props: {
    visible: { type: Boolean, default: false },
    title: { type: String, default: '选择位置' },
    initialLongitude: { type: [Number, String], default: null },
    initialLatitude: { type: [Number, String], default: null },
    initialAddress: { type: String, default: '' }
  },
  data() {
    return {
      visibleProxy: this.visible,
      map: null,
      marker: null,
      geocoder: null,
      searchService: null,
      autocomplete: null,
      keyword: '',
      longitude: this.initialLongitude ? Number(this.initialLongitude) : null,
      latitude: this.initialLatitude ? Number(this.initialLatitude) : null,
      address: this.initialAddress || ''
    }
  },
  watch: {
    visible(val) {
      this.visibleProxy = val
    },
    visibleProxy(val) {
      this.$emit('input', val)
    }
  },
  methods: {
    onOpen() {
      this.initMap()
    },
    async initMap() {
      const qq = await loadTencentMap().catch(err => {
        this.$message.error(err.message || '地图加载失败')
        throw err
      })

      const center = (this.longitude != null && this.latitude != null)
        ? new qq.maps.LatLng(this.latitude, this.longitude)
        : new qq.maps.LatLng(39.9042, 116.4074) // 默认北京

      if (!this.map) {
        this.map = new qq.maps.Map(this.$refs.mapContainer, {
          center,
          zoom: 12
        })

        // 地图点击选点
        qq.maps.event.addListener(this.map, 'click', (e) => {
          this.setPoint(e.latLng, qq)
          this.reverseGeocode(e.latLng, qq)
        })

        // 初始化Geocoder
        this.geocoder = new qq.maps.Geocoder({
          complete: (result) => {
            if (result && result.detail && result.detail.location) {
              const { lat, lng } = result.detail.location
              this.latitude = lat
              this.longitude = lng
              this.address = result.detail.address || this.address
              this.setMarker(result.detail.location, qq)
              this.map.setCenter(result.detail.location)
            }
          }
        })

        // 搜索服务
        this.searchService = new qq.maps.SearchService({
          complete: (res) => {
            if (res.detail && res.detail.pois && res.detail.pois.length > 0) {
              const first = res.detail.pois[0]
              const latLng = first.latLng
              this.address = first.address || first.name
              this.setPoint(latLng, qq)
              this.map.setCenter(latLng)
            } else {
              this.$message.warning('未找到相关地点')
            }
          }
        })

        // 自动完成（输入框绑定）
        this.$nextTick(() => {
          const inputEl = this.$el.querySelector('.search-input input')
          if (inputEl) {
            this.autocomplete = new qq.maps.place.Autocomplete(inputEl)
            qq.maps.event.addListener(this.autocomplete, 'confirm', (res) => {
              if (res && res.value) {
                this.keyword = res.value
                this.onSearch()
              }
            })
          }
        })
      } else {
        this.map.setCenter(center)
      }

      // 初始化已有点
      if (this.longitude != null && this.latitude != null) {
        const latLng = new qq.maps.LatLng(this.latitude, this.longitude)
        this.setMarker(latLng, qq)
        this.map.setCenter(latLng)
      }
    },
    onSearch() {
      if (!this.keyword) return
      if (this.searchService) {
        this.searchService.search(this.keyword)
      }
    },
    setPoint(latLng, qq) {
      this.latitude = latLng.getLat()
      this.longitude = latLng.getLng()
      this.setMarker(latLng, qq)
    },
    setMarker(latLng, qq) {
      if (!this.marker) {
        this.marker = new qq.maps.Marker({
          position: latLng,
          map: this.map
        })
      } else {
        this.marker.setPosition(latLng)
      }
    },
    reverseGeocode(latLng, qq) {
      if (this.geocoder) {
        this.geocoder.getAddress(latLng)
      }
    },
    close() {
      this.visibleProxy = false
    },
    confirm() {
      if (this.longitude == null || this.latitude == null) {
        this.$message.warning('请先在地图中选择位置')
        return
      }
      this.$emit('confirm', {
        longitude: this.longitude,
        latitude: this.latitude,
        address: this.address
      })
      this.close()
    }
  }
}
</script>

<style scoped>
.map-toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 12px;
}
.search-input {
  flex: 1;
}
.coord-display {
  display: flex;
  gap: 12px;
  color: #606266;
}
.map-container {
  width: 100%;
  height: 480px;
  border: 1px solid #e4e7ed;
  border-radius: 4px;
}
</style> 